/*
 * Copyright (C) 2017
 *
 * Brick Yang <printfxxx@163.com>
 *
 * This program is free software. You can redistribute it and/or
 * modify it as you like.
 */

/**
 * @file	dpmng.c
 * @brief	dpmng driver
 */

#include <mtrace.h>

#include "dpmng.h"

/* Command versioning */
#define DPMNG_CMD_BASE_VERSION	1
#define DPMNG_CMD_ID_OFFSET	4

#define DPMNG_CMD(id)	(((id) << DPMNG_CMD_ID_OFFSET) | DPMNG_CMD_BASE_VERSION)

/* Command IDs */
#define DPMNG_CMDID_VERSION		DPMNG_CMD(0x831)
#define DPMNG_CMDID_GET_SOC_VERSION	DPMNG_CMD(0x832)

struct dpmng_rsp_get_version {
	/* cmd word 0 */
	__le32 revision;
	__le32 version_major;
	/* cmd word 1 */
	__le32 version_minor;
};

struct dpmng_rsp_get_soc_version {
	/* cmd word 0 */
	__le32 svr;
	__le32 pvr;
};

int mc_get_version(struct fsl_mc_io *mc_io,
		   u32 cmd_flags,
		   struct mc_version *mc_ver_info)
{
	struct fsl_mc_command cmd = { 0 };
	struct dpmng_rsp_get_version *dpmng_rsp;
	int err;

	/* prepare command */
	cmd.header = mc_encode_cmd_header(DPMNG_CMDID_VERSION,
					  cmd_flags,
					  0);

	/* send command to mc */
	err = mc_send_command(mc_io, &cmd);
	if (err)
		return err;

	/* retrieve response parameters */
	dpmng_rsp = (struct dpmng_rsp_get_version *)cmd.params;
	mc_ver_info->revision = le32_to_cpu(dpmng_rsp->revision);
	mc_ver_info->major = le32_to_cpu(dpmng_rsp->version_major);
	mc_ver_info->minor = le32_to_cpu(dpmng_rsp->version_minor);

	return 0;
}

int mc_get_soc_version(struct fsl_mc_io *mc_io,
		       u32 cmd_flags,
		       struct mc_soc_version *mc_soc_ver_info)
{
	struct fsl_mc_command cmd = { 0 };
	struct dpmng_rsp_get_soc_version *dpmng_rsp;
	int err;

	/* prepare command */
	cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_SOC_VERSION,
					  cmd_flags,
					  0);

	/* send command to mc */
	err = mc_send_command(mc_io, &cmd);
	if (err)
		return err;

	/* retrieve response parameters */
	dpmng_rsp = (struct dpmng_rsp_get_soc_version *)cmd.params;
	mc_soc_ver_info->svr = le32_to_cpu(dpmng_rsp->svr);
	mc_soc_ver_info->pvr = le32_to_cpu(dpmng_rsp->pvr);

	return 0;
}
